Skip to content

fix(directus): ticket invoice schema follow-up (user_created FK, read-only invoice links) - #257

Closed
claude[bot] wants to merge 2 commits into
mainfrom
claude/ticket-invoices-schema-followup
Closed

claude[bot] wants to merge 2 commits into
mainfrom
claude/ticket-invoices-schema-followup

Conversation

@claude

@claude claude Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Requested by Dennis Becker · Slack thread

Before: In production, ticket_invoices.user_created is a bare UUID. It has no foreign key and no relation to directus_users, even though #248's hand-written snapshot declared one. In the App, the ticket_orders.invoices O2M can be edited. Deselecting an invoice would try to set its order to null, which fails because the column is NOT NULL. "Select existing" could move an invoice document to a different order. The legacy pointers ticket_orders.invoice_number and invoice_file can also be edited by hand, although the bundle maintains them (current-document pointer, invoice numbering, backfill).

After: ticket_invoices.user_created gets a real FK and relation to directus_users.id. ticket_orders.invoices, invoice_number and invoice_file are read-only in the App, with notes explaining why. No fields, relations or data are removed.

How: These are hand edits to directus-cms/schema.json on top of the production snapshot from #251, in the same format:

  • The new relation is modeled on the other 39 user_created/user_updated relations. It uses the same <table>_user_created_foreign naming, one_deselect_action: nullify and ON DELETE NO ACTION.
  • The field-level foreign_key_table/foreign_key_column is set to match.
  • readonly in field meta only affects the App. The bundle writes these fields through ItemsService, and that keeps working.

Depends on #251. This branch is based on #251's snapshot commit, so please merge #251 first; this diff then shrinks to the single commit here. After merging, run directus schema apply against production.

Before applying, check that there are no orphaned creator IDs, otherwise adding the FK fails:
SELECT count(*) FROM ticket_invoices t LEFT JOIN directus_users u ON u.id = t.user_created WHERE t.user_created IS NOT NULL AND u.id IS NULL; (expected result: 0)

Validation:

Review points

  • Addressed: the Codex point to restore the invoice creator FK and relation.
  • Addressed: the Copilot point that order is non-nullable while the O2M uses nullify. Instead of changing the deselect action (the only other option, delete, would be destructive), the O2M is now read-only, so documents can't be detached or re-linked. The DB-level ON DELETE NO ACTION on order stays. Blocking the deletion of an order that has invoices is intended.
  • Addressed (partly): the Copilot point about legacy order-level invoice fields. They are not removed, because the bundle still reads and writes them (issueOriginalInvoice, generateInvoiceNumber, lifecycle regenerate, backfill). They are now read-only and labelled as maintained automatically.
  • Deliberately not changed: sent_at read-only. The ticket-order-processing hook's Slack alert tells admins to set sent_at manually when stamping it fails after the email went out, so it has to stay editable in the App.
  • Deliberately not changed: user_created uses ON DELETE NO ACTION, not SET NULL. This matches every other user relation in the schema and keeps the audit attribution. A user who created invoice documents has to be suspended rather than hard-deleted.
  • Deliberately not changed: the other Copilot nitpicks (archive_app_filter without an archive field, the column name order, the index on type, invoice_number being required and read-only). They are cosmetic or would mean a disruptive rename.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G9qwzY9WrCDrT5NX7zNP1E


Generated by Claude Code

- Add the missing ticket_invoices.user_created -> directus_users FK and
  relation (ON DELETE NO ACTION, like every other user_created relation
  in the snapshot), so the acting admin on corrections/cancellations is
  a real, referentially intact relation.
- Make the ticket_orders.invoices O2M read-only in the App: documents
  must never be detached from their order (the order FK is NOT NULL, so
  a "nullify" deselect could only fail) or re-linked to another order.
- Mark the ticket_orders.invoice_number / invoice_file pointers as
  read-only with a note: they are still written and read by the bundle
  (current-document pointer, numbering, backfill) and must not be edited
  by hand. No fields or data are removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9qwzY9WrCDrT5NX7zNP1E
@vercel

vercel Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
programmierbar-website Ready Ready Preview Sep 23, 2026 1:36pm UTC

Request Review

@Jan0707
Jan0707 marked this pull request as ready for review September 23, 2026 13:34
Copilot AI lite review requested due to automatic review settings September 23, 2026 13:34
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-23T13:37:39.962010Z 1529687 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved approval-blocking issues remain.

Review effort: Lite
Findings: None

What changed in this PR

Updates the Directus invoice schema to preserve creator attribution and prevent unsafe manual invoice edits.

Changes:

  • Adds the user_created foreign key and relation.
  • Makes invoice links and legacy invoice pointers read-only.
File Description
directus-cms/​schema.json Adds the creator relation and read-only invoice metadata.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@claude

claude Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

Closing: schema changes should come from the Directus UI, not hand-edits of schema.json. The three changes (relation on ticket_invoices.user_created → directus_users, readonly ticket_orders.invoices, readonly legacy invoice_number/invoice_file) will be made directly in Directus and picked up by the next schema snapshot PR.


Generated by Claude Code

@claude claude Bot closed this Sep 23, 2026

This branch was successfully deployed

1 active deployment
Preview — 51a9eb89 Deployed Sep 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants